package main

import (
  "io"
  "os"
  "fmt"
  "bytes"
  "net/http"
  "encoding/json"
)

// 输出格式化后的 json 串
func dumpJson(jsonStr []byte) {
  var prettyJSON bytes.Buffer
  err := json.Indent(&prettyJSON, jsonStr, "", "  ")
  if err != nil {
    fmt.Fprintf(os.Stderr, "%s\nformat error, %v\n", string(jsonStr), err)
  } else {
    fmt.Println(prettyJSON.String())
  }
}

// 获取 http 响应体 []byte，可多次调用，根据谁申请资源谁释放的原则，此处不关闭 resp.Body
func readRespBody(resp *http.Response) ([]byte, error) {
  body, err := io.ReadAll(resp.Body)
  if err != nil {
    return nil, fmt.Errorf("read body: %w", err)
  }
  // 重建 body, 方便可能的后继读取
  resp.Body = io.NopCloser(bytes.NewReader(body))
  return body, nil
}

// 解析 JSON 到 T 类型的结构体
func parseJSONResponse[T any](j []byte) (*T, error) {
  var r T
  if err := json.Unmarshal(j, &r); err != nil {
    return nil, fmt.Errorf("decode json: %w", err)
  }
  return &r, nil
}

// 将 JSON 类型的响应体解析到 T 类型的结构体
func parseResp[T any](resp *http.Response) (*T, error) {
  body, err := readRespBody(resp)
  if err != nil {
    return nil, err
  }
  return parseJSONResponse[T](body)
}
